package nezumi.gui;

import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;

import javax.imageio.ImageIO;

/**
 * A sprite resource manager (load & cache forever). Its often quite important
 * how and where you get your resources from. In most cases it makes sense to
 * have a central resource loader that goes away, gets your resources and caches
 * them for future use.
 * <p>
 * [singleton]
 * <p>
 * 
 * @author rui
 */
public class SpriteStore {
	/** The single instance of this class */
	private static SpriteStore single = new SpriteStore();

	/**
	 * Get the single instance of this class
	 * 
	 * @return The single instance of this class
	 */
	public static SpriteStore get() {
		return single;
	}

	/** The cached sprite map, from reference to sprite instance */
	private HashMap<String, Sprite> sprites = new HashMap<String, Sprite>();

	/**
	 * Retrieve a sprite from the store.
	 * 
	 * @param ref
	 *            The reference to the image to use for the sprite
	 * @return A sprite instance containing an accelerate image of the request
	 *         reference
	 * @throws IOException 
	 */
	public Sprite getSprite(String ref) throws IOException {
		// if we've already got the sprite in the cache
		// then just return the existing version
		if (sprites.get(ref) != null) {
			return (Sprite) sprites.get(ref);
		}

		// otherwise, go away and grab the sprite from the resource
		// loader
		BufferedImage sourceImage = null;
		
		// The ClassLoader.getResource() ensures we get the sprite
		// from the appropriate place, this helps with deploying the game
		// with things like webstart. You could equally do a file look
		// up here.
		URL url = this.getClass().getClassLoader().getResource(ref);

		// use ImageIO to read the image in
		sourceImage = ImageIO.read(url);

		// create an accelerated image of the right size to store our sprite in
		GraphicsConfiguration gc = GraphicsEnvironment
				.getLocalGraphicsEnvironment().getDefaultScreenDevice()
				.getDefaultConfiguration();
		Image image = gc.createCompatibleImage(sourceImage.getWidth(),
				sourceImage.getHeight(), Transparency.BITMASK);

		// draw our source image into the accelerated image
		image.getGraphics().drawImage(sourceImage, 0, 0, null);

		// create a sprite, add it the cache then return it
		Sprite sprite = new Sprite(image);
		sprites.put(ref, sprite);

		return sprite;
	}
}